#include "CRUsersManager.h"
#include "StringConverter.h"
#include "ResourceManager.h"
#include "Database/DatabaseEnv.h"
#include "StringConverter.h"
#include "json/json.h"
#include "NGLog.h"
#include "Character.h"
#include "CharManager.h"
#include "Items.h"
#include "ItemManager.h"
#include "Users.h"
#include "UserManager.h"
#include "Channels.h"
#include "ChannelManager.h"
#include "Towns.h"
#include "TownManager.h"
#include "ItemModelManager.h"
#include "Message.h"
#include "CenterBankManager.h"
#include "VipCardManager.h"
#include "Tools.h"
#include "XMLData.h"
#include "GameDefine.h"
#include XMLDATA_MGR_PATH
#include LOGIC_MGR_PATH
#include LOG_MGR_PATH
#include PROTOCOLS_MGR_PATH
#include "OpcodesEx.h"
#include "WorldPacket.h"
#include "AIInterface.h"
#include "WSSocketManager.h"
#include "json/json.h"
#include "ProtocolDealEnums.h"
#include "url.h"


//=============================组局信息相关===================================
bool CRUserManager::AddCRUser(CRUser & cru)
{
	Fields fields;
	sDataMgr.initData(DataManager::DatabaseTypeCenter, DB_NAME_CRUSERS, &fields);
	
	fields["status"] = cru.status;
	fields["bind_phone"] = cru.bind_phone;
	fields["openid"] = cru.openid;
	fields["openkey"] = cru.openkey;
	fields["qbopenid"] = cru.qbopenid;
	fields["unionid"] = cru.unionid;
	fields["agentid"] = cru.agentid;
	fields["access_token"] = cru.access_token;
	fields["access_time"] = cru.access_time;
	fields["push_client_id"] = cru.push_client_id;
	fields["push_token"] = cru.push_token;
	fields["push_notice"] = cru.push_notice;
	fields["push_vibration"] = cru.push_vibration;
	fields["push_disturb"] = cru.push_disturb;
	fields["nickname"] = cru.nickname;
	fields["icon_url"] = cru.icon_url;
	fields["gender"] = cru.gender;
	fields["attentions"] = cru.attentions;
	fields["fans"] = cru.fans;
	fields["friends"] = cru.friends;
	fields["ip"] = cru.ip;
	fields["ip_addr"] = cru.ip_addr;
	fields["shop_id"] = cru.shop_id;
	fields["refer"] = cru.refer;
	fields["create_time"] = cru.create_time;
	fields["last_time"] = cru.last_time;
	fields["login_count"] = cru.login_count;
	fields["judge_level"] = cru.judge_level;
	fields["judge_count"] = cru.judge_count;
	fields["judge_total_stars"] = cru.judge_total_stars;
	fields["judge_effect_label"] = cru.judge_effect_label;
	fields["start_game_count"] = cru.start_game_count;
	fields["play_game_count"] = cru.play_game_count;
	fields["total_winlose_score"] = cru.total_winlose_score;
	
	if (!sDataMgr.insertData(DataManager::DatabaseTypeCenter, DB_NAME_CRUSERS, &fields))
		return false;
	
	cru.uid = fields["uid"].GetUInt32();
	return true;
}

bool CRUserManager::UpdateCRUser(const CRUser & cru)
{
	Fields fields;
	
	fields["status"] = cru.status;
	fields["bind_phone"] = cru.bind_phone;
	fields["openid"] = cru.openid;
	fields["openkey"] = cru.openkey;
	fields["qbopenid"] = cru.qbopenid;
	fields["unionid"] = cru.unionid;
	fields["agentid"] = cru.agentid;
	fields["access_token"] = cru.access_token;
	fields["access_time"] = cru.access_time;
	fields["push_client_id"] = cru.push_client_id;
	fields["push_token"] = cru.push_token;
	fields["push_notice"] = cru.push_notice;
	fields["push_vibration"] = cru.push_vibration;
	fields["push_disturb"] = cru.push_disturb;
	fields["nickname"] = cru.nickname;
	fields["icon_url"] = cru.icon_url;
	fields["gender"] = cru.gender;
	fields["attentions"] = cru.attentions;
	fields["fans"] = cru.fans;
	fields["friends"] = cru.friends;
	fields["ip"] = cru.ip;
	fields["ip_addr"] = cru.ip_addr;
	fields["shop_id"] = cru.shop_id;
	fields["refer"] = cru.refer;
	fields["create_time"] = cru.create_time;
	fields["last_time"] = cru.last_time;
	fields["login_count"] = cru.login_count;
	fields["judge_level"] = cru.judge_level;
	fields["judge_count"] = cru.judge_count;
	fields["judge_total_stars"] = cru.judge_total_stars;
	fields["judge_effect_label"] = cru.judge_effect_label;
	fields["start_game_count"] = cru.start_game_count;
	fields["play_game_count"] = cru.play_game_count;
	fields["total_winlose_score"] = cru.total_winlose_score;
	
	int count = sDataMgr.updateDataQueryAffected(DataManager::DatabaseTypeCenter, DB_NAME_CRUSERS, 
									&fields, "`uid` = %u", cru.uid);
	
	return count > 0;
}

#define SQLBUFER_LEN 16384

bool CRUserManager::UpdateCRUser(Fields * fields, const char * QueryString, ...)
{
	char sql[SQLBUFER_LEN] = ""; 
	va_list vlist; 
	va_start(vlist, QueryString); 
	vsnprintf(sql, SQLBUFER_LEN, QueryString, vlist); 
	va_end(vlist);
	int count = sDataMgr.updateDataQueryAffected(DataManager::DatabaseTypeCenter, DB_NAME_CRUSERS, fields, sql);
	return count > 0;
}

bool CRUserManager::UpdateCRUser(const uint32 &cru_id, Fields * fields)
{
	int count = sDataMgr.updateDataQueryAffected(DataManager::DatabaseTypeCenter, DB_NAME_CRUSERS, fields, 
												"`uid` = %u", cru_id);
	return count > 0;
}


bool CRUserManager::GetCRUser(const uint32 & cru_id, CRUser * cru)
{
	assert (cru);
	FieldRows rows;
	sDataMgr.getDatas(DataManager::DatabaseTypeCenter, DB_NAME_CRUSERS, &rows, "`uid` = %u", cru_id);
	if (rows.empty())
		return false;
	
	Fields fields = rows.front();
	cru->uid = fields["uid"].GetUInt32();
	cru->status = fields["status"].GetUInt32();
	
	cru->bind_phone = fields["bind_phone"].GetValue();
	cru->openid = fields["openid"].GetValue();
	cru->openkey = fields["openkey"].GetValue();
	cru->qbopenid = fields["qbopenid"].GetValue();
	cru->unionid = fields["unionid"].GetValue();
	
	cru->agentid = fields["agentid"].GetUInt32();
	cru->access_token = fields["access_token"].GetValue();
	cru->access_time = fields["access_time"].GetUInt32();
	
	cru->push_client_id = fields["push_client_id"].GetValue();
	cru->push_token = fields["push_token"].GetValue();
	cru->push_notice = fields["push_notice"].GetUInt32();
	cru->push_vibration = fields["push_vibration"].GetUInt32();
	cru->push_disturb = fields["push_disturb"].GetUInt32();
	
	cru->nickname = fields["nickname"].GetValue();
	cru->icon_url = fields["icon_url"].GetValue();
	cru->gender = fields["gender"].GetUInt32();
	cru->attentions = fields["attentions"].GetUInt32();
	cru->fans = fields["fans"].GetUInt32();
	cru->friends = fields["friends"].GetUInt32();
	
	cru->ip = fields["ip"].GetValue();
	cru->ip_addr = fields["ip_addr"].GetValue();
	cru->shop_id = fields["shop_id"].GetUInt32();
	cru->refer = fields["refer"].GetUInt32();
	cru->create_time = fields["create_time"].GetValue();
	cru->last_time = fields["last_time"].GetUInt32();
	cru->login_count = fields["login_count"].GetUInt32();
	
	cru->judge_level = fields["judge_level"].GetFloat();
	cru->judge_count = fields["judge_count"].GetUInt32();
	cru->judge_total_stars = fields["judge_total_stars"].GetUInt32();
	cru->judge_effect_label = fields["judge_effect_label"].GetValue();
	cru->start_game_count = fields["start_game_count"].GetUInt32();
	cru->play_game_count = fields["play_game_count"].GetUInt32();
	cru->total_winlose_score = fields["total_winlose_score"].GetInt32();
	
	return true;
}

uint32 CRUserManager::GetCRUsersList(std::list<CRUser> * lstData, const char * query,...)
{
	va_list argp;
	va_start(argp, query);
	lstData->clear();
	FieldRows fieldRows;
	
	char sql[SQLBUFER_LEN] = ""; 
	va_list vlist; 
	va_start(vlist, query); 
	vsnprintf(sql, SQLBUFER_LEN, query, vlist); 
	va_end(vlist);
	
	if (!sDataMgr.getDatas(DataManager::DatabaseTypeCenter, DB_NAME_CRUSERS, &fieldRows, sql))
		return 0;
	
	FieldRows::iterator iter, enditer = fieldRows.end();
	for (iter = fieldRows.begin(); iter != enditer; ++ iter)
	{
		CRUser cru;
		Fields &fields = *iter;
		
		cru.uid = fields["uid"].GetUInt32();
		cru.status = fields["status"].GetUInt32();
		
		cru.bind_phone = fields["bind_phone"].GetValue();
		cru.openid = fields["openid"].GetValue();
		cru.openkey = fields["openkey"].GetValue();
		cru.qbopenid = fields["qbopenid"].GetValue();
		cru.unionid = fields["unionid"].GetValue();
		
		cru.agentid = fields["agentid"].GetUInt32();
		cru.access_token = fields["access_token"].GetValue();
		cru.access_time = fields["access_time"].GetUInt32();
		
		cru.push_client_id = fields["push_client_id"].GetValue();
		cru.push_token = fields["push_token"].GetValue();
		cru.push_notice = fields["push_notice"].GetUInt32();
		cru.push_vibration = fields["push_vibration"].GetUInt32();
		cru.push_disturb = fields["push_disturb"].GetUInt32();
		
		cru.nickname = fields["nickname"].GetValue();
		cru.icon_url = fields["icon_url"].GetValue();
		cru.gender = fields["gender"].GetUInt32();
		cru.attentions = fields["attentions"].GetUInt32();
		cru.fans = fields["fans"].GetUInt32();
		cru.friends = fields["friends"].GetUInt32();
		
		cru.ip = fields["ip"].GetValue();
		cru.ip_addr = fields["ip_addr"].GetValue();
		cru.shop_id = fields["shop_id"].GetUInt32();
		cru.refer = fields["refer"].GetUInt32();
		cru.create_time = fields["create_time"].GetValue();
		cru.last_time = fields["last_time"].GetUInt32();
		cru.login_count = fields["login_count"].GetUInt32();
		
		cru.judge_level = fields["judge_level"].GetFloat();
		cru.judge_count = fields["judge_count"].GetUInt32();
		cru.judge_total_stars = fields["judge_total_stars"].GetUInt32();
		cru.judge_effect_label = fields["judge_effect_label"].GetValue();
		cru.start_game_count = fields["start_game_count"].GetUInt32();
		cru.play_game_count = fields["play_game_count"].GetUInt32();
		cru.total_winlose_score = fields["total_winlose_score"].GetInt32();
		
		lstData->push_back(cru);
	}
	
	return lstData->size();
}

bool CRUserManager::UpdateUserIpAddr(const uint32 & uid, String ip, String ip_addr)
{
	CRUser cru;
	if(!GetCRUser(uid, &cru))
		return false;
	
	Fields fields;
	fields["ip"] = ip;
	fields["ip_addr"] = ip_addr;
	fields["last_time"] = time(0);
	
	UpdateCRUser(uid, &fields);
	return true;
}


//-------------------------------用户配置信息-----------------------------
bool UserConfigManager::AddUserConfig(UserConfig & uc)
{
	Fields fields;
	// sDataMgr.initData(DataManager::DatabaseTypeCenter, DB_NAME_USERCONFIG, &fields);
	sDataMgr.initData(DataManager::DatabaseTypeInfo, DB_NAME_USERCONFIG, &fields);
	
	fields["group_id"] = 1;
	fields["status"] = uc.status;
	fields["pid"] = uc.pid;
	fields["last_gzid"] = uc.last_gzid;
	fields["last_gameid"] = uc.last_gameid;
	fields["last_mode"] = uc.last_mode;
	fields["user_data"] = uc.user_data;
	fields["config"] = uc.config;
	fields["info"] = uc.info;
	fields["create_time"] = sGLMgr.GetCurDateTime();
	
	// if (!sDataMgr.insertData(DataManager::DatabaseTypeCenter, DB_NAME_USERCONFIG, &fields))
	if (!sDataMgr.insertData(DataManager::DatabaseTypeInfo, DB_NAME_USERCONFIG, &fields))
		return false;
	
	uc.config_id = fields["config_id"].GetUInt32();
	return true;
}

bool UserConfigManager::UpdateUserConfig(const UserConfig & uc)
{
	Fields fields;
	
	fields["status"] = uc.status;
	fields["pid"] = uc.pid;
	fields["last_gzid"] = uc.last_gzid;
	fields["last_gameid"] = uc.last_gameid;
	fields["last_mode"] = uc.last_mode;
	fields["user_data"] = uc.user_data;
	fields["config"] = uc.config;
	fields["info"] = uc.info;
	
	// int count = sDataMgr.updateDataQueryAffected(DataManager::DatabaseTypeCenter, DB_NAME_USERCONFIG, &fields, "`config_id` = %u", uc.config_id);
	int count = sDataMgr.updateDataQueryAffected(DataManager::DatabaseTypeInfo, DB_NAME_USERCONFIG, &fields, "`config_id` = %u", uc.config_id);
	
	return count > 0;
}

#define SQLBUFER_LEN 16384

bool UserConfigManager::UpdateUserConfig(Fields * fields, const char * QueryString, ...)
{
	char sql[SQLBUFER_LEN] = ""; 
	va_list vlist; 
	va_start(vlist, QueryString); 
	vsnprintf(sql, SQLBUFER_LEN, QueryString, vlist); 
	va_end(vlist);
	// int count = sDataMgr.updateDataQueryAffected(DataManager::DatabaseTypeCenter, DB_NAME_USERCONFIG, fields, sql);
	int count = sDataMgr.updateDataQueryAffected(DataManager::DatabaseTypeInfo, DB_NAME_USERCONFIG, fields, sql);
	return count > 0;
}

bool UserConfigManager::UpdateUserConfig(const uint32 &config_id, Fields * fields)
{
	// int count = sDataMgr.updateDataQueryAffected(DataManager::DatabaseTypeCenter, DB_NAME_USERCONFIG, fields, "`config_id` = %u", config_id);
	int count = sDataMgr.updateDataQueryAffected(DataManager::DatabaseTypeInfo, DB_NAME_USERCONFIG, fields, "`config_id` = %u", config_id);
	return count > 0;
}

bool UserConfigManager::GetUserConfig(const uint32 & config_id, UserConfig * uc)
{
	assert (uc);
	FieldRows rows;
	// sDataMgr.getDatas(DataManager::DatabaseTypeCenter, DB_NAME_USERCONFIG, &rows, "`config_id` = %u", config_id);
	sDataMgr.getDatas(DataManager::DatabaseTypeInfo, DB_NAME_USERCONFIG, &rows, "`config_id` = %u", config_id);
	if (rows.empty())
		return false;
	
	Fields fields = rows.front();
	uc->config_id = fields["config_id"].GetUInt32();
	uc->group_id = fields["group_id"].GetUInt32();
	uc->status = fields["status"].GetUInt32();
	uc->pid = fields["pid"].GetUInt32();
	uc->last_gzid = fields["last_gzid"].GetUInt32();
	uc->last_gameid = fields["last_gameid"].GetUInt32();
	uc->last_mode = fields["last_mode"].GetUInt32();
	
	uc->last_time = fields["last_time"].GetValue();
	uc->user_data = fields["user_data"].GetValue();
	uc->config = fields["config"].GetValue();
	uc->info = fields["info"].GetValue();
	uc->create_time = fields["create_time"].GetValue();
	
	return true;
}

uint32 UserConfigManager::GetUserConfigList(std::list<UserConfig> * lstData, const char * query,...)
{
	va_list argp;
	va_start(argp, query);
	lstData->clear();
	FieldRows fieldRows;
	
	char sql[SQLBUFER_LEN] = ""; 
	va_list vlist; 
	va_start(vlist, query); 
	vsnprintf(sql, SQLBUFER_LEN, query, vlist); 
	va_end(vlist);
	
	// if (!sDataMgr.getDatas(DataManager::DatabaseTypeCenter, DB_NAME_USERCONFIG, &fieldRows, sql))
	if (!sDataMgr.getDatas(DataManager::DatabaseTypeInfo, DB_NAME_USERCONFIG, &fieldRows, sql))
		return 0;
	
	FieldRows::iterator iter, enditer = fieldRows.end();
	for (iter = fieldRows.begin(); iter != enditer; ++ iter)
	{
		UserConfig uc;
		Fields &fields = *iter;
		
		uc.config_id = fields["config_id"].GetUInt32();
		uc.group_id = fields["group_id"].GetUInt32();
		uc.status = fields["status"].GetUInt32();
		uc.pid = fields["pid"].GetUInt32();
		uc.last_gzid = fields["last_gzid"].GetUInt32();
		uc.last_gameid = fields["last_gameid"].GetUInt32();
		uc.last_mode = fields["last_mode"].GetUInt32();
		
		uc.last_time = fields["last_time"].GetValue();
		uc.user_data = fields["user_data"].GetValue();
		uc.config = fields["config"].GetValue();
		uc.info = fields["info"].GetValue();
		uc.create_time = fields["create_time"].GetValue();
		
		lstData->push_back(uc);
	}
	
	return lstData->size();
}

// 添加或更新游戏记录
bool UserConfigManager::AddCenterBattleConfig(String & config)
{
	Json::Value val;
	Json::Reader reader;
	
	reader.parse(config, val);
	if(val.empty())
		return false;
	
	uint32 pid = val["pid"].asUInt();
	uint32 gz_id = val["gz_id"].asUInt();
	uint32 game_id = val["game_id"].asUInt();
	uint32 mode = val["mode"].asUInt();
	
	Json::FastWriter w;
	
	bool bFindData = false;
	bool bExist = false;
	uint8 val_index = 0;
	
	UserConfig uc;
	Json::Value valRecord;
	std::list<UserConfig> lstData;
	if(GetUserConfigList(&lstData, "`pid` = %u and status < 255", pid))
	{// 更新数据
		bExist = true;
		uc = *lstData.begin();
		
		reader.parse(uc.config, valRecord);
		for (Json::Value::iterator iterVal=valRecord.begin(); iterVal!=valRecord.end(); ++iterVal)
		{
			uint32 record_gameid = (*iterVal)["game_id"].asUInt();
			uint32 record_mode = (*iterVal)["mode"].asUInt();
			if(record_gameid == game_id && record_mode == mode)
			{
				(*iterVal)["limit_loop"] = val["limit_loop"].asUInt();		// 限制轮次
				(*iterVal)["top_times"] = val["top_times"].asUInt();		// 封顶
				(*iterVal)["battle_name"] = val["battle_name"].asString();	// 房间名字
				(*iterVal)["extra_data"] = val["extra_data"].asString();	// 附加玩法
				
				bFindData = true;
				break;
			}
		}
		
		val_index = valRecord.size();
		
		if(bFindData)
		{// 找到数据，更新记录
			Fields fields;
			fields["config"] = w.write(valRecord);
			fields["last_gzid"] = gz_id;						// 记录最后一次创建分区信息
			fields["last_gameid"] = game_id;
			fields["last_mode"] = mode;
			fields["last_time"] = sGLMgr.GetCurDateTime();		// 记录更新时间
			
			UpdateUserConfig(uc.config_id, &fields);
		}
	}
	
	if(!bFindData)
	{// 未找到数据，添加数据
		if(!bExist)
		{
			uc.pid = pid;
			uc.last_gzid = gz_id;				// 记录最后一次创建分区信息
			uc.last_gameid = game_id;
			uc.last_mode = mode;
		}
		
		valRecord[val_index] = val;
		uc.config = w.write(valRecord);
		
		if(!bExist)
		{
			return AddUserConfig(uc);
		}
		else
		{
			return UpdateUserConfig(uc);
		}
	}
	
	return false;
}

// 获得游戏记录
String UserConfigManager::GetCenterBattleConfig(const uint32 & pid, const uint32 & game_id, const uint32 & mode)
{
	if(!pid || !game_id || !mode)
		return "";
	
	std::list<UserConfig> lstData;
	if(GetUserConfigList(&lstData, "`pid` = %u and status < 255", pid))
	{// 更新数据
		UserConfig uc = *lstData.begin();
		
		Json::Value valRecord;
		Json::Reader reader;
		Json::FastWriter w;
		reader.parse(uc.config, valRecord);
		
		for (Json::Value::iterator iterVal=valRecord.begin(); iterVal!=valRecord.end(); ++iterVal)
		{
			uint32 record_gameid = (*iterVal)["game_id"].asUInt();
			uint32 record_mode = (*iterVal)["mode"].asUInt();
			Log.Debug("GetCenterBattleConfig","record_gameid[%u] record_mode[%u]", record_gameid, record_mode);
			if(record_gameid == game_id && record_mode == mode)
			{
				return w.write(*iterVal);
			}
		}
		
	}
	
	return "";
}
